/*******************************************************************************
* Copyright (c) 2010, 2018 西安秦晔信息科技有限公司
* Licensed under the Apache License, Version 2.0 (the "License");
*    you may not use this file except in compliance with the License.
*    You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*    Unless required by applicable law or agreed to in writing, software
*    distributed under the License is distributed on an "AS IS" BASIS,
*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*    See the License for the specific language governing permissions and
*    limitations under the License.
*******************************************************************************/
package com.qinyeit.serviceapp.service.stores.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.qinyeit.serviceapp.entity.*;
import com.qinyeit.serviceapp.entity.enums.PaymentState;
import com.qinyeit.serviceapp.entity.enums.PurchaseState;
import com.qinyeit.serviceapp.entity.enums.StoreInState;
import com.qinyeit.serviceapp.entity.enums.StoreInType;
import com.qinyeit.serviceapp.exception.BusinessRunTimeException;
import com.qinyeit.serviceapp.repository.stores.PurchaseOrderDetailRepository;
import com.qinyeit.serviceapp.repository.stores.StoreInOrderDetailRepository;
import com.qinyeit.serviceapp.service.dishes.DishesStoreService;
import com.qinyeit.serviceapp.service.materials.PurchaseSpecService;
import com.qinyeit.serviceapp.service.stores.StockService;
import com.qinyeit.serviceapp.service.stores.StoreInOrderService;
import com.qinyeit.serviceapp.utils.CompuUtils;
import com.qinyeit.serviceapp.utils.LocalUtils;
import com.qinyetech.springstage.core.date.DateUtils;
import com.qinyetech.springstage.core.lang.QyMap;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.qinyetech.springstage.core.service.BaseService;
import com.qinyeit.serviceapp.repository.stores.PurchaseOrderRepository;
import com.qinyeit.serviceapp.service.stores.PurchaseOrderService;

import java.util.*;

/** 
 * ClassName: PurchaseOrderServiceImpl <br/> 
 * Function: 采购订单 业务实现 <br/> 
 * date: 2018-11-08 14:00:02 <br/> 
 * 
 * @author liuwenjin
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@Transactional
public class PurchaseOrderServiceImpl extends BaseService<PurchaseOrder, Long> implements PurchaseOrderService {


	@Autowired
	private PurchaseOrderRepository purchaseOrderRepository;
	@Autowired
	private PurchaseOrderDetailRepository purchaseOrderDetailRepository;
	@Autowired
	private StoreInOrderDetailRepository storeInOrderDetailRepository;
	@Autowired
	private StoreInOrderService storeInOrderService;
	@Autowired
	private PurchaseSpecService purchaseSpecService;
	@Autowired
	private StockService stockService;
	@Autowired
	private DishesStoreService dishesStoreService;



	@Override
	public void saveDate(JSONObject data,Long merchantGroupId) {

		//获取订单信息
		JSONObject orderData = data.getJSONObject("purchaseOrder");
		//订单明细
		JSONArray detailData = data.getJSONArray("details");

		//获取提交类型
		int type = data.getInteger("type");

		if(CollectionUtils.isEmpty(detailData)){
			throw new BusinessRunTimeException("订单明细为空",1001);
		}
		if(orderData.getLong("supplierId")==null){
			throw new BusinessRunTimeException("请选择供应商，供应商不能为空",10001);
		}
		if(type==3){
			if(orderData.getLong("warehouseId")==null){
				throw new BusinessRunTimeException("请选择入库仓库，仓库不能为空",10002);
			}
		}


		Long id = orderData.getLong("id");
		PurchaseOrder purchaseOrder = null;
		if(id!=null){
			//编辑
			purchaseOrder = this.findById(id);
			//删除订单明细
			purchaseOrderRepository.deleteOrderDetails(id,merchantGroupId);
		}else {
			//新建
			purchaseOrder = new PurchaseOrder();
			purchaseOrder.setNo(LocalUtils.getOrderNo());
		}

		purchaseOrder.setAddress(orderData.getString("address"));
		purchaseOrder.setRemark(orderData.getString("remark"));
		purchaseOrder.setSupplierId(orderData.getLong("supplierId"));
		purchaseOrder.setSupplierName(orderData.getString("supplierName"));

		DishesStore store = dishesStoreService.findById(orderData.getLong("storeId"));
		purchaseOrder.setStoreId(orderData.getLong("storeId"));
		purchaseOrder.setStoreName(store.getName());
		purchaseOrder.setMerchantGroupId(merchantGroupId);


		if(type==1){
			//保存
			purchaseOrder.setPurchaser(null);
			purchaseOrder.setPurchaserName(null);
			purchaseOrder.setPurchaseTime(DateUtils.date());
			purchaseOrder.setState(PurchaseState.NOAUDIT);
		}else if(type==2){
			//提交并审核
			purchaseOrder.setChecker(null);
			purchaseOrder.setCheckerName(null);
			purchaseOrder.setState(PurchaseState.AUDIT);
			purchaseOrder.setCheckTime(DateUtils.date());
			purchaseOrder.setPurchaseTime(DateUtils.date());
			purchaseOrder.setSendTime(new Date());
		}else if(type==3) {
			//确认收货
			purchaseOrder.setAcceptTime(DateUtils.date());
			purchaseOrder.setWarehouseId(orderData.getLong("warehouseId"));
			purchaseOrder.setWarehouseName(orderData.getString("warehouseName"));
			purchaseOrder.setState(PurchaseState.INSTORAGE);

		}
		//订单总金额
		double totalAmount = 0.0;
		//订单明细
		JSONObject item ;
		List<PurchaseOrderDetail> detailList = Lists.newArrayList();
		PurchaseOrderDetail detail = null;
		PurchaseSpec spec = null;
		for (int i=0;i<detailData.size();i++){
			item = detailData.getJSONObject(i);
			detail = new PurchaseOrderDetail();
			spec = purchaseSpecService.findById(item.getLong("specId"));
			detail.setOrder(purchaseOrder);
			detail.setSpecId(item.getLong("specId"));
			detail.setNo(item.getString("no"));
			detail.setName(item.getString("name"));
			detail.setSpec(item.getString("spec")); //物料规格型号
			detail.setPurchaseSpec(item.getString("purchaseSpec")); //采购规格型号 name
			detail.setPurchaseUnit(item.getString("purchaseUnit")); // 采购规格单位
			detail.setUnit(item.getString("unit")); //库存单位
			detail.setCreateAt(DateUtils.date());
			detail.setRemark(item.getString("remark"));
			detail.setMerchantGroupId(merchantGroupId);
			if(spec!=null){
				detail.setCode(spec.getMaterial().getCode());
			}
			detail.setHistoryPrice(item.getDouble("purchaseNewPrice"));

			//确认收货
			if(type==3){
				detail.setRealCount(item.getDouble("realCount"));
				detail.setRealPrice(item.getDouble("realPrice"));
				if(spec!=null){
					detail.setStockCount(spec.getRatio()==null?0:CompuUtils.multiply(spec.getRatio(),item.getDouble("realCount")));//规格比例*数量
				}
				detail.setCount(item.getDouble("count"));
				detail.setPrice(item.getDouble("price"));
				detail.setAmount(CompuUtils.multiply(detail.getRealCount(),detail.getRealPrice()));
				//库存进出明细
//				TODO 暂时将库存直接入库 不保存库存进出明细

				detail.setHistoryPrice(item.getDouble("realPrice"));
				//保存最新一次进货价格
				if(spec!=null){
					spec.setHistoryPrice(item.getDouble("realPrice"));
					purchaseSpecService.update(spec);
				}
			}else {
				detail.setCount(item.getDouble("count"));
				detail.setPrice(item.getDouble("price"));
				detail.setAmount(CompuUtils.multiply(item.getDouble("count"),item.getDouble("price")));
				detail.setStockCount(spec.getRatio()==null?0:CompuUtils.multiply(spec.getRatio(),item.getDouble("count")));//规格比例*数量
			}

			detailList.add(detail);
			totalAmount = CompuUtils.add(totalAmount,detail.getAmount());
		}
		purchaseOrderDetailRepository.saveAll(detailList);
		purchaseOrder.setAmount(totalAmount);
		purchaseOrder = this.update(purchaseOrder);


		if(PurchaseState.INSTORAGE==purchaseOrder.getState()){
			//保存入库单
			log.info(">>>>>>>>>>>>>{}",purchaseOrder);
			log.info(">>>>>>>>>>>>>{}",detailList);
			log.info(">>>>>>>>>>>>>{}",orderData.getDouble("payAmount"));
			log.info(">>>>>>>>>>>>>{}",orderData.getDouble("giftAmount"));

			this.saveStoreInOrder(purchaseOrder,detailList,orderData.getDouble("payAmount"),orderData.getDouble("giftAmount"));
//			//保存库存
//			this.saveStore(purchaseOrder,detailList);

		}



	}

	/**
	 * 库存保存
	 * @param purchaseOrder
	 * @param detailList
	 */
	private void saveStore(PurchaseOrder purchaseOrder,List<PurchaseOrderDetail> detailList){
		if(CollectionUtils.isEmpty(detailList)){
			throw new BusinessRunTimeException("订单明细为空",10001);
		}

		List<QyMap> list = new ArrayList<>();
		QyMap map = null; // 物料 、成本金额 、库存金额、数量
		String key = "";//M_物料id
		PurchaseSpec spec = null;
		Stock stock = null;
		double cost = 0.0;
		for (PurchaseOrderDetail detail : detailList) {
			spec = purchaseSpecService.findById(detail.getSpecId());
			stock = stockService.getStocks(purchaseOrder.getWarehouseId(),spec.getMaterial().getId(),purchaseOrder.getMerchantGroupId());
			if(stock!=null){
				//有库存 计算成本均价
				cost = (CompuUtils.add(
						CompuUtils.multiply(stock.getCount(),stock.getCost()),
						CompuUtils.multiply(detail.getStockCount(),detail.getPrice()
						)))/(CompuUtils.add(stock.getCount(),detail.getStockCount()));
				stock.setCost(cost);
				stock.setCount(CompuUtils.add(stock.getCount(),CompuUtils.multiply(spec.getRatio(),detail.getRealCount())));
				stock.setAmount(CompuUtils.add(stock.getAmount(),detail.getAmount()));
			}else {
				stock = new Stock();
				stock.setWarehouseId(purchaseOrder.getWarehouseId());
				stock.setMaterialId(spec.getMaterial().getId());
				stock.setMerchantGroupId(detail.getMerchantGroupId());
				stock.setCount(CompuUtils.multiply(spec.getRatio(),detail.getRealCount()));
				//总价/数量
				stock.setCost(CompuUtils.divide(CompuUtils.multiply(spec.getRatio(),detail.getRealPrice()),CompuUtils.multiply(spec.getRatio(),detail.getRealCount())));
				stock.setAmount(CompuUtils.multiply(stock.getCost(),stock.getCount()));
			}
			stockService.update(stock);
		}
	}


	/**
	 * 保存入库单据
	 * @param purchaseOrder
	 * @param detailList
	 */
	private void saveStoreInOrder(PurchaseOrder purchaseOrder,List<PurchaseOrderDetail> detailList,Double payAmount,Double giftAmount){

		if(CollectionUtils.isEmpty(detailList)){
			throw new BusinessRunTimeException("订单明细为空",10001);
		}
		if(payAmount==null){
			payAmount = 0.0;
		}if(giftAmount==null){
			giftAmount=0.0;
		}
		StoreInOrder storeInOrder = new StoreInOrder();
		storeInOrder.setSupplierId(purchaseOrder.getSupplierId());
		storeInOrder.setSupplierName(purchaseOrder.getSupplierName());
		storeInOrder.setWarehouseId(purchaseOrder.getWarehouseId());
		storeInOrder.setWarehouseName(purchaseOrder.getWarehouseName());
		storeInOrder.setNo(DateFormatUtils.format(Calendar.getInstance(), "yyMMddHHmmssSSS"));
		storeInOrder.setAmount(purchaseOrder.getAmount());
		storeInOrder.setInTime(DateUtils.date());
		storeInOrder.setState(StoreInState.AUDIT);
		storeInOrder.setType(StoreInType.SHOUHUOIN);
		storeInOrder.setStoreId(purchaseOrder.getStoreId());
		storeInOrder.setStoreName(purchaseOrder.getStoreName());
		storeInOrder.setMerchantGroupId(purchaseOrder.getMerchantGroupId());
		storeInOrder.setPayAmount(payAmount);
		storeInOrder.setGiftAmount(giftAmount);
		storeInOrder.setOperatorName(purchaseOrder.getCheckerName());
//		log.info(purchaseOrder.getAmount());
//		log.info(payAmount);
//		log.info(giftAmount);

		double cha = CompuUtils.add(2,purchaseOrder.getAmount(),payAmount*(-1),giftAmount*(-1));
		if(cha<0){
			throw new BusinessRunTimeException("实付金额不能大于订单总金额",10002);
		}
		if(cha==0){
			storeInOrder.setPaymentState(PaymentState.SETTLED);
		}else {
			storeInOrder.setPaymentState(PaymentState.NORMAL);
		}
		storeInOrderService.save(storeInOrder);

		//明细
		List<StoreInOrderDetail> storeInOrderDetails = new ArrayList<>();
		PurchaseSpec purchaseSpec = null;
		for (PurchaseOrderDetail detail : detailList) {
			purchaseSpec = purchaseSpecService.findById(detail.getSpecId());
			StoreInOrderDetail storeInOrderDetail = new StoreInOrderDetail();
			storeInOrderDetail.setOrder(storeInOrder);
			storeInOrderDetail.setNo(detail.getNo());
			storeInOrderDetail.setName(detail.getName());
			storeInOrderDetail.setSpecId(detail.getSpecId());
			storeInOrderDetail.setSpec(detail.getSpec());
			storeInOrderDetail.setCount(detail.getRealCount());
			storeInOrderDetail.setPrice(detail.getRealPrice());
			storeInOrderDetail.setMaterialId(purchaseSpec.getMaterial().getId());
			storeInOrderDetail.setPurchaseUnit(purchaseSpec.getUnit());
			storeInOrderDetail.setPurchaseSpec(purchaseSpec.getName());
			storeInOrderDetail.setTotal(CompuUtils.multiply(detail.getRealCount(),detail.getRealPrice()));
			storeInOrderDetail.setUnit(detail.getUnit());
			storeInOrderDetail.setMerchantGroupId(detail.getMerchantGroupId());
			storeInOrderDetail.setStorageCount(CompuUtils.multiply(purchaseSpec.getRatio(),detail.getRealCount()));
			storeInOrderDetail.setStoragePrice(detail.getRealPrice()/storeInOrderDetail.getStorageCount()); //实收金额/库存数量
			storeInOrderDetail.setStorageUnit(purchaseSpec.getMaterial().getUnit());
			storeInOrderDetail.setStorageTotal(detail.getAmount());
			storeInOrderDetail.setCode(detail.getCode());
			storeInOrderDetails.add(storeInOrderDetail);
		}
		storeInOrderDetailRepository.saveAll(storeInOrderDetails);

		//保存库存
		stockService.saveStore(storeInOrder,storeInOrderDetails);

		//入库收款
		if(CompuUtils.compareTo(storeInOrder.getPayAmount(),0)>0){
			storeInOrderService.saveReceivePaymentOrders(storeInOrder);
		}

	}


}